import createjs from 'createjs-ts'
import Setting from './Setting'
import { GameMap } from './Sprite'
import CrumbManager from './CrumbManager'
import SnakeManager from './SnakeManager'
import MapManager from './MapManager'
import { getPixelRatio, browserRedirect } from './Util'
const Ticker = createjs.Ticker;
const Point = createjs.Point;
const Matrix2D = createjs.Matrix2D;
let tempFunc = null
export class GameManager {
	constructor({canvas, velocityRegion, gameOverFunc}) {
		this.renderEnv = browserRedirect();
		this.canvas = canvas;
		this.velocityRegion = velocityRegion
		this.ctx = canvas.getContext('2d');
		this.ratio = getPixelRatio(this.ctx);
		this.stage = void 0,
		this.gameMapLayer = void 0, // 游戏背景图
		this.player = void 0,
		this.mode = void 0,
		this.timeAll = 0;
		this.gameOverFunc = gameOverFunc;
		this.isUsingProp = false // 是否使用道具中
		this.gameFps = 0
		this.init()
		this.initGameControlBtn()
	}
	init() {
		// polyfill 提供了这个方法用来获取设备的 pixel ratio
		// 获取分辨比率 
		const ratio = getPixelRatio(this.ctx);
		// 获取body的宽高
		const actualBounds = window.document.body.getBoundingClientRect();

		// 横屏需要转换
		// const temp = actualBounds.height
		// actualBounds.height = actualBounds.width
		// actualBounds.width = temp
		// Setting.SCREEN_WIDTH = this.canvas.getBoundingClientRect().height * ratio;
		// Setting.SCREEN_HEIGHT = this.canvas.getBoundingClientRect().width * ratio;

		Setting.SCREEN_WIDTH = this.canvas.getBoundingClientRect().width * ratio;
		Setting.SCREEN_HEIGHT = this.canvas.getBoundingClientRect().height * ratio;

		this.canvas.style.width = actualBounds.width + "px";
		this.canvas.style.height = actualBounds.height + "px";
		this.canvas.width = Setting.SCREEN_WIDTH;
		this.canvas.height = Setting.SCREEN_HEIGHT;
		this.stage = new createjs.Stage(this.canvas);
		this.initGameMap(); // 初始化地图
		this.initCrumb(); // 初始化实物
		this.initSnake(); // 初始化蛇
	}
	/**
 * 初始化游戏背景图
 */
	initGameMap() {
		this.gameMapLayer = new GameMap({
			x: (Setting.SCREEN_WIDTH - Setting.PLAYGROUND_WIDTH) / 2,
			y: (Setting.SCREEN_HEIGHT - Setting.PLAYGROUND_HEIGHT) / 2,
			width: Setting.PLAYGROUND_WIDTH,
			height: Setting.PLAYGROUND_HEIGHT
		});
		this.stage.addChild(this.gameMapLayer);
	}
	/**
	 * 初始化食物
	 */
	initCrumb() {
		CrumbManager.init(this.gameMapLayer);
	}

	/**
	 *初始化蛇
	 * @returns snake
	 */
	initSnake() {
		this.player = SnakeManager.init(this.gameMapLayer);
		return this.player
	}

	/**
 * 重新开始
 */
	refresh() {
		this.stage.removeAllChildren();
		this.stage.clear();
		MapManager.clear();
		CrumbManager.clear();
		SnakeManager.clear();
		// gameEndScene.style.display = "none";

		if (this.mode === 'time') {
			this.initTimer();
		}
		this.initGameMap();
		this.initCrumb();
		this.player = this.initSnake()
	}
	/**
	 * 复活
	 */
	revivePlayer() {
		this.player.revivePlayer()
	}
	initGameControlBtn() {
		/**
		 * 左侧移动轮盘
		 */
		this.motionRegion = window.document.getElementById("motionhandler")
		this.motionBtn = this.motionRegion.querySelector("button.MotionControler")
		this.motionBounds = this.motionBtn.getBoundingClientRect()
		this.motionCenter = {
			x: this.motionBounds.left + this.motionBounds.width / 2,
			y: this.motionBounds.top + this.motionBounds.height / 2
		};
	}
	transCoord(x, y) {
		let deltaX = x - this.motionCenter.x,
			deltaY = y - this.motionCenter.y,
			mod = Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2));
		deltaX /= mod, deltaY /= mod;
		const newDeltaXy = {
			x: deltaX,
			y: deltaY
		}
		// 修改强制 横屏 状态不一致
		let transMtx = new Matrix2D()
		transMtx.rotate(-90).transformPoint(newDeltaXy.x, newDeltaXy.y, newDeltaXy)
		this.player.RotateTo(new Point(newDeltaXy.x, newDeltaXy.y));
		// 轮盘方向
		this.motionBtn.style.transform = "translate(" + newDeltaXy.x * this.motionBounds.width / 2 + "px," + newDeltaXy.y * this.motionBounds.height / 2 + "px)";
	}

	/**
 * 移动端触摸监听
 * @param {} evt 
 * @returns 
 */
	touchHandler(evt) {
		evt.stopPropagation();
		evt.preventDefault();
		if (evt.touches.length > 2 || evt.type == "touchend" && evt.touches.length > 0) return;
		let x, y;
		if (evt.touches.length == 1) {
			let touch = evt.changedTouches[0];
			x = touch.clientX
			y = touch.clientY
		} else {
			let touch1 = evt.changedTouches[0],
				touch2 = evt.changedTouches[0];
			let x1 = touch1.clientX,
				y1 = touch1.clientY,
				x2 = touch2.clientX,
				y2 = touch2.clientY;
				x = x1 > x2 ? x2 : x1
				y = x1 > x2 ? y2 : y1;
		}
		this.transCoord(x, y);
	}

	addEventListener() {
		const type = browserRedirect();
		// alert(type)
		if (type == "mobile") {
			this.motionRegion.addEventListener("touchstart", (e) => this.touchHandler(e));
			this.motionRegion.addEventListener("touchmove", (e) => this.touchHandler(e));
			this.motionRegion.addEventListener("touchend", (e) => this.backCoord(e));
			this.velocityRegion.addEventListener("touchstart", (e) => this.velocityHandler(e));
			this.velocityRegion.addEventListener("touchend", () => {
				if(this.isUsingProp !== 'speed') {
					this.player.setAccelerate(false)
				}
			})
			// 用户旋转设备的时候触发
			window.addEventListener("orientationchange", () => {
				const temp = Setting.SCREEN_WIDTH;
				Setting.SCREEN_WIDTH = Setting.SCREEN_HEIGHT;
				Setting.SCREEN_HEIGHT = temp;
				this.canvas.width = Setting.SCREEN_WIDTH;
				this.canvas.height = Setting.SCREEN_HEIGHT;
				this.canvas.style.left = 0 + "px";
			});
		}
	
		if (type == "pc") {
			this.addPCEventListener();
		}
	}

	addPCEventListener() {
		document.addEventListener("keydown", (event) => {
			if (event.defaultPrevented) {
				return; // Should do nothing if the key event was already consumed.
			}
			// console.log(event.key + " down");
			switch (event.key) {
				case "a":
					this.player.setAccelerate(true);
					this.velocityRegion.classList.add("active");
					break;
				default:
					return; // Quit when this doesn't handle the key event.
			}
		}, false);
		document.addEventListener("keyup", (event) => {
			if (event.defaultPrevented) {
				return; // Should do nothing if the key event was already consumed.
			}
			switch (event.key) {
				case "a":
					this.player.setAccelerate(false);
					this.velocityRegion.classList.remove("active");
					break;
				default:
					return; // Quit when this doesn't handle the key event.
			}
		}, false);
		let down = false;
		document.body.addEventListener("mousedown", () => {
			down = true;
		});
		document.body.addEventListener("mousemove",  (event) =>{
			if (down) {
				this.transCoordPC(event.clientX, event.clientY);
			}
		});
		document.body.addEventListener("mouseup", () =>{
			this.backCoord();
		})
	}
	/**
	 * 
	 * @param {number} clientX 鼠标在视图的横坐标
	 * @param {number} clientY 鼠标在视图的竖坐标
	 */
	transCoordPC(clientX, clientY) {
		// 
		let deltaX = clientX - (window.innerWidth / 2) // 鼠标位置减去 屏幕中心位置， 横轴距离
		let deltaY = clientY - (window.innerHeight / 2)
		
		let mod = Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2)) // 算出 到鼠标位置的直线距离
		deltaX /= mod
		deltaY /= mod;
		this.player.RotateTo(new Point(deltaX, deltaY));
		this.motionBtn.style.transform = "translate(" + deltaX * this.motionBounds.width / 2 + "px," + deltaY * this.motionBounds.height / 2 + "px)";
	}

	backCoord() {
		this.motionBtn.style.transform = "translate(0px,0px)";
	}
	// 触摸加速键
	velocityHandler(evt) {
		evt.stopPropagation();
		evt.preventDefault();
		if (evt.touches.length > 2 || evt.type == "touchend" && evt.touches.length > 0) return;
		this.player.setAccelerate(true);
	}
	update() {
		Ticker.timingMode = Ticker.RAF;
		Ticker.framerate = 60;
		Ticker.addEventListener("tick", this.stage);
		Ticker.addEventListener("tick", () => {
			// 更新fps
			this.gameFps = Ticker.getMeasuredFPS().toFixed(0)
			// console.log()
		});
		tempFunc= (e) => this.updateManager(e)
		Ticker.addEventListener("tick", tempFunc);
	}
	updateManager(event) {
		// event.delta 是自上次 tick 以来经过的时间（
		SnakeManager.updateSnakeMap(event.delta, (score, kill) => {
			// 打开游戏结束面板， 显示分数和杀敌数
			// console.log("score: " + score + " kill: " + kill);
			// alert("score: " + score + " kill: " + kill);
			this.gameOverFunc({
				score,
				kill,
				player: this.player
			});
			if (this.mode === 'time') {
				Ticker.removeEventListener("tick", this.timerHandler);
			}
		}, this);

		// 刷新食物
		CrumbManager.update(event.delta)

		// 滚动屏幕
		this.gameMapLayer.setTransform(Setting.SCREEN_WIDTH / 2 - this.player.headPos.x, Setting.SCREEN_HEIGHT / 2 - this.player.headPos.y);
	}

	initTimer() {
		this.timeAll = 60 * 1000
		Ticker.addEventListener("tick", this.timerHandler);
	}
	timerHandler(evt) {
		this.timeAll -= evt.delta;
		if (this.timeAll <= 0) {
			this.timeAll = 0;
			// 打开游戏结束面板， 显示分数和杀敌数
			console.log("time out");
			this.player.sentenceDie();
			Ticker.removeEventListener("tick", this);
		}
		const now = new Date(this.timeAll),
			nowSecond = now.getSeconds(),
			nowMillionSecond = (now.getMilliseconds() / 10).toFixed(0);
		let str = "TIME: ";
		str += nowSecond / 10 > 1 ? nowSecond + '' : '0' + nowSecond;
		str += ':';
		str += nowMillionSecond / 10 > 1 ? nowMillionSecond + '' : '0' + nowMillionSecond;
		console.log(str);
		// FPS下面的时间
		// timeremain.innerText = str;
	}
	useSpeedProp(type) {
		this.isUsingProp = type
		if(type === 'speed') {
			this.player.setAccelerate(true)
			setTimeout(() => {
				this.isUsingProp = false
				this.player.setAccelerate(false)
			}, 10 * 1000)
		} else if(type === 'addLength') {
			this.player.updateLength(5)
			setTimeout(() => {
				this.isUsingProp = false
			}, 10 * 1000)
		}
	}
	closeGame() {
		this.stage.removeAllChildren();
		this.stage.clear();
		MapManager.clear();
		CrumbManager.clear();
		SnakeManager.clear();
		Ticker.removeEventListener("tick", tempFunc);
	}
}
